#include "../../src/detail/box_config_impl.hh"
#include "../../src/util/os_util.hh"
#include "../framework/unittest.hh"
#include <fstream>

FIXTURE_BEGIN(test_config)

SETUP([]() {
  std::ofstream ofs;
  ofs.open("config.cfg", std::ios::trunc | std::ios::out);
  ofs << "listener = {"
         "   host = (\"127.0.0.1:10001\")"
         "}"
         "service_finder = {"
         "	type = \"test_type\""
         "	hosts = \"10.0.128.214:2181\""
         "}"
         "box_channel_recv_buffer_len = 1024 "
         "box_name = \"test_box\""
         "logger_config_line=\"config_line\""
         "service = {"
         "   service_dir = \"test_dir\""
         "   preload_service = <1:\"1.so\", 2:\"2.so\">"
         "}"
         "connect_other_box_timeout = 2000 "
         "service_finder_connect_timeout = 2000 "
         "open_coroutine = \"false\""
         "necessary_service = (\"test\", \"test1\")";
  ofs.close();

  std::ofstream ofs_new;
  ofs_new.open("config_new.cfg", std::ios::trunc | std::ios::out);
  ofs_new << "listener = {"
             "   host = (\"127.0.0.1:10001\")"
             "}"
             "service_finder = {"
             "	type = \"test_type\""
             "	hosts = \"10.0.128.214:2181\""
             "}"
             "box_channel_recv_buffer_len = 1024 "
             "box_name = \"test_box\""
             "logger_config_line=\"config_new_line\""
             "service = {"
             "   service_dir = \"test_dir\""
             "   preload_service = <1:\"1.so\", 2:\"2.so\">"
             "}"
             "connect_other_box_timeout = 5000 "
             "service_finder_connect_timeout = 2000 "
             "necessary_service = (\"test\", \"test1\")";
  ofs_new.close();
})

CASE(TestConfig1) {
  kratos::config::BoxConfigImpl bc(nullptr);
  std::string error;
  ASSERT_TRUE(bc.load("config.cfg", error));
  ASSERT_TRUE(bc.get_box_channel_recv_buffer_len() == 1024);
  ASSERT_TRUE(bc.get_box_name() == "test_box");
  ASSERT_TRUE(bc.get_connect_other_box_timeout() == 2000);
  ASSERT_TRUE(bc.get_listener_list().front() == "127.0.0.1:10001");
  ASSERT_TRUE(bc.get_logger_config_line() == "config_line");
  ASSERT_TRUE(bc.get_service_dir() == "test_dir");
  ASSERT_TRUE(bc.get_service_finder_connect_timeout() == 2000);
  ASSERT_TRUE(bc.get_service_finder_type() == "test_type");
  ASSERT_TRUE(bc.get_service_finder_hosts() == "10.0.128.214:2181");
  ASSERT_TRUE(
      bc.get_preload_service().find("1") != bc.get_preload_service().end() &&
      bc.get_preload_service().find("2") != bc.get_preload_service().end());
  ASSERT_TRUE(bc.get_necessary_service().front() == "test");
  ASSERT_TRUE(!bc.is_open_coroutine());
}

CASE(TestConfig2) {
  kratos::config::BoxConfigImpl bc(nullptr);
  std::string error;
  ASSERT_TRUE(!bc.load("../wrong/config.cfg", error));
}

CASE(TestReload1) {
  kratos::config::BoxConfigImpl bc(nullptr);
  std::string error;
  ASSERT_TRUE(bc.load("config.cfg", error));
  bool call = false;
  bc.add_reload_listener(
      "test", [&](const std::string&, const kratos::config::BoxConfig &) { call = true; });
  ASSERT_TRUE(bc.reload("config_new.cfg", error));
  ASSERT_TRUE(call);
  ASSERT_TRUE(bc.get_connect_other_box_timeout() == 5000);
  ASSERT_TRUE(bc.get_logger_config_line() == "config_new_line");
  ASSERT_TRUE(bc.remove_reload_listener("test"));
}

CASE(TestReload2) {
  kratos::config::BoxConfigImpl bc(nullptr);
  std::string error;
  ASSERT_TRUE(bc.load("config.cfg", error));
  ASSERT_TRUE(nullptr != bc.get_config_ptr());
  bool call = false;
  bc.add_reload_listener(
      "test", [&](const std::string&,const kratos::config::BoxConfig &) { call = true; });
  ASSERT_TRUE(!bc.reload("wrong_config.cfg", error));
  ASSERT_TRUE(!call);
  ASSERT_TRUE(bc.get_connect_other_box_timeout() == 2000);
  ASSERT_TRUE(bc.get_logger_config_line() == "config_line");
}

TEARDOWN([]() {
  kratos::util::remove_file("config.cfg");
  kratos::util::remove_file("config_new.cfg");
})

FIXTURE_END(test_config)
